#ifndef __GLSL_OGL__
#define __GLSL_OGL__

//Class based on OpenGL 4.0 Shading Cookbook by David Wolff with some adds and modifications
//@TODO - Functionality Redesign

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <GL\glew.h>

#include <glm\glm.hpp>
#include <glm\gtc\type_ptr.hpp>

using namespace std;
using namespace glm;

namespace GlslShader
{
   enum GlslShaderType
   {
      VERTEX, FRAGMENT, GEOMETRY, TESS_CONTROL, TESS_EVALUATION
   };
};

class Glsl
{
   int handle;
   bool linked;
   string logString;

   char *textFileRead (char *fn);
   int getUniformLocation (const char *name);
   bool fileExists (const string &filename);

   void setShaders ();
   void printProgramInfoLog (GLuint obj);
   void printShaderInfoLog (GLuint obj);
public:
   Glsl (); //define your own way to compile and link shaders
   Glsl (char *vert, char *geom, char *frag);

   bool compileShaderFile (const char *filename, GlslShader::GlslShaderType type);
   bool compileShaderString (const string & source, GlslShader::GlslShaderType type);
   bool link ();
   bool isLinked ();

   string log ();
   int getHandle ();
   
   void useProgram (bool isActive);
   void bindAttribLocation (GLuint location, const char *name);
   void bindFragDataLocation (GLuint location, const char *name);
   void setUniform (const char *name, float x, float y, float z);
   void setUniform (const char *name, const int numVertices, vec3 *v);
   void setUniform (const char *name, const vec3 & v);
   void setUniform (const char *name, const vec4 & v);
   void setUniform (const char *name, const mat4 & m);
   void setUniform (const char *name, const mat3 & m);
   void setUniform (const char *name, float val);
   void setUniform (const char *name, int val);
   void setUniform (const char *name, bool val);
   void setUniformBlock (glm::mat4 modelView, glm::mat4 normalMatrix, glm::mat4 projection);
   void printActiveUniforms ();
   void printActiveAttribs ();
   ~Glsl ();
};

#endif